package me.stone.stanimeclient.core.data.di

import android.content.Context
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import me.stone.stanimeclient.core.common.di.IoDispatcher
import me.stone.stanimeclient.core.data.repository.RemoteFanDataRepository
import me.stone.stanimeclient.core.model.FanDetailData
import me.stone.stanimeclient.core.model.FanSimpleItem
import me.stone.stanimeclient.core.model.FanWeekUpdateData
import okio.buffer
import okio.source
import java.nio.charset.Charset
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class FakeRemoteFanDataRepository @Inject constructor(
    @ApplicationContext private val context: Context,
    @IoDispatcher private val dispatcher: CoroutineDispatcher
): RemoteFanDataRepository {

    private suspend fun getJsonString(filename: String): String? {
        val result: String?
        withContext(dispatcher) {
            result = try {
                val buffer = context.assets.open(filename).source().buffer()
                buffer.readString(Charset.defaultCharset())
            } catch (e: Exception) {
                null
            }
        }
        return result
    }

    private val gson by lazy { Gson() }

    override suspend fun listBannerData(): List<FanSimpleItem> {
        val result: List<FanSimpleItem>
        withContext(dispatcher) {
            val json = getJsonString("banner_data.json")
            result = gson.fromJson(json, object : TypeToken<List<FanSimpleItem>>(){}.type)
        }
        return result
    }

    override suspend fun listUpdateData(): List<FanWeekUpdateData> {
        val result: List<FanWeekUpdateData>
        withContext(dispatcher) {
            val json = getJsonString("daily_update_data.json")
            result = gson.fromJson(json, object : TypeToken<List<FanWeekUpdateData>>(){}.type)
        }
        return result
    }

    override suspend fun listLimitRecommend(): List<FanSimpleItem> {
        val result: List<FanSimpleItem>
        withContext(dispatcher) {
            val json = getJsonString("limit_recommend_data.json")
            result = gson.fromJson(json, object : TypeToken<List<FanSimpleItem>>(){}.type)
        }
        return result
    }

    override suspend fun listRecommendData(): RemoteFanDataRepository.SimplePageResponse {
        val result: RemoteFanDataRepository.SimplePageResponse
        withContext(dispatcher) {
            val json = getJsonString("recommend_data.json")
            result = gson.fromJson(json,
                object : TypeToken<RemoteFanDataRepository.SimplePageResponse>(){}.type
            )
        }
        return result
    }

    override suspend fun loadRankDataList(premiereYear: Int?): RemoteFanDataRepository.RankResponse {
        val result: RemoteFanDataRepository.RankResponse
        withContext(dispatcher) {
            val json = getJsonString("rank_data.json")
            result = gson.fromJson(json,
                object : TypeToken<RemoteFanDataRepository.RankResponse>(){}.type
            )
        }
        return result
    }

    override suspend fun loadRecentUpdateList(
        page: Int,
        pageSize: Int
    ): RemoteFanDataRepository.SimplePageResponse {
        val result: RemoteFanDataRepository.SimplePageResponse
        withContext(dispatcher) {
            val json = getJsonString("recent_update_data.json")
            result = gson.fromJson(json,
                object : TypeToken<RemoteFanDataRepository.SimplePageResponse>(){}.type
            )
        }
        return result
    }

    override suspend fun loadCatalogList(
        page: Int,
        filter: Map<String, String>,
        pageSize: Int
    ): RemoteFanDataRepository.DetailPageResponse {
        val result: RemoteFanDataRepository.DetailPageResponse
        withContext(dispatcher) {
            val json = getJsonString("catalog_data.json")
            result = gson.fromJson(json,
                object : TypeToken<RemoteFanDataRepository.DetailPageResponse>(){}.type
            )
        }
        return result
    }

    override suspend fun searchFanDataList(
        query: String,
        page: Int
    ): RemoteFanDataRepository.SearchResponse {
        val result: RemoteFanDataRepository.SearchResponse
        withContext(dispatcher) {
            val json = getJsonString("search_data.json")
            result = gson.fromJson(json,
                object : TypeToken<RemoteFanDataRepository.SearchResponse>(){}.type
            )
        }
        return result
    }

    override suspend fun queryFanData(id: Int): FanDetailData {
        val result: FanDetailData
        withContext(dispatcher) {
            val json = getJsonString("fan_data.json")
            result = gson.fromJson(json,
                object : TypeToken<FanDetailData>(){}.type
            )
        }
        return result
    }

}